* lisp-mode.el (lisp-fill-paragraph): New function.
authorJim Blandy <jimb@redhat.com>
Sun, 14 Feb 1993 14:33:44 +0000 (14:33 +0000)
committerJim Blandy <jimb@redhat.com>
Sun, 14 Feb 1993 14:33:44 +0000 (14:33 +0000)
(shared-lisp-mode-map): Bind M-q to lisp-fill-paragraph.

lisp/emacs-lisp/lisp-mode.el

index b0f823e010378bd80903f3a1bb9eb6246d273185..ca4649846134b2dfc20f39cc3000bd54ecfd0b35 100644 (file)
     ()
    (setq shared-lisp-mode-map (make-sparse-keymap))
    (define-key shared-lisp-mode-map "\e\C-q" 'indent-sexp)
+   (define-key shared-lisp-mode-map "\M-q" 'lisp-fill-paragraph)
    (define-key shared-lisp-mode-map "\177" 'backward-delete-char-untabify)
    (define-key shared-lisp-mode-map "\t" 'lisp-indent-line))
 
@@ -593,6 +594,75 @@ ENDPOS is encountered."
       (indent-sexp endmark)
       (set-marker endmark nil))))
 \f
+;;;; Lisp paragraph filling commands.
+
+(defun lisp-fill-paragraph (&optional justify)
+  "Like \\[fill-paragraph], but handle Emacs Lisp comments.
+If any of the current line is a comment, fill the comment or the
+paragraph of it that point is in, preserving the comment's indentation
+and initial semicolons."
+  (interactive "P")
+  (let (
+       ;; Non-nil if the current line contains a comment.
+       has-comment
+
+       ;; If has-comment, the appropriate fill-prefix for the comment.
+       comment-fill-prefix
+       )
+
+    ;; Figure out what kind of comment we are looking at.
+    (save-excursion
+      (beginning-of-line)
+      (cond
+
+       ;; A line with nothing but a comment on it?
+       ((looking-at "[ \t]*;[; \t]*")
+       (setq has-comment t
+             comment-fill-prefix (buffer-substring (match-beginning 0)
+                                                   (match-end 0))))
+
+       ;; A line with some code, followed by a comment?  Remember that the
+       ;; semi which starts the comment shouldn't be part of a string or
+       ;; character.
+       ((progn
+         (while (not (looking-at ";\\|$"))
+           (skip-chars-forward "^;\n\"\\\\?")
+           (cond
+            ((eq (char-after (point)) ?\\) (forward-char 2))
+            ((memq (char-after (point)) '(?\" ??)) (forward-sexp 1))))
+         (looking-at ";+[\t ]*"))
+       (setq has-comment t)
+       (setq comment-fill-prefix
+             (concat (make-string (current-column) ? )
+                     (buffer-substring (match-beginning 0) (match-end 0)))))))
+
+    (if (not has-comment)
+       (fill-paragraph justify)
+
+      ;; Narrow to include only the comment, and then fill the region.
+      (save-restriction
+       (narrow-to-region
+        ;; Find the first line we should include in the region to fill.
+        (save-excursion
+          (while (and (zerop (forward-line -1))
+                      (looking-at "^[ \t]*;")))
+          ;; We may have gone to far.  Go forward again.
+          (or (looking-at "^[ \t]*;")
+              (forward-line 1))
+          (point))
+        ;; Find the beginning of the first line past the region to fill.
+        (save-excursion
+          (while (progn (forward-line 1)
+                        (looking-at "^[ \t]*;")))
+          (point)))
+
+       ;; Lines with only semicolons on them can be paragraph boundaries.
+       (let ((paragraph-start (concat paragraph-start "\\|^[ \t;]*$"))
+             (paragraph-separate (concat paragraph-start "\\|^[ \t;]*$"))
+             (fill-prefix comment-fill-prefix))
+         (fill-paragraph justify))))))
+
+\f
 (defun indent-code-rigidly (start end arg &optional nochange-regexp)
   "Indent all lines of code, starting in the region, sideways by ARG columns.
 Does not affect lines starting inside comments or strings, assuming that